import Router from 'koa-router';
import jwt from 'jsonwebtoken'
import Redis from 'koa-redis'
// 用来发邮件的
import nodeMailer from 'nodemailer'

import Passport from './utils/passport'
import Email from '../dbs/config'
import axios from './utils/axios'
import UserModel from '../dbs/models/users'
import inspectorsModel from '../dbs/models/inspectors'
import StudentModel from '../dbs/models/student'

let router = new Router({ prefix: '/users' })

// 获取redis客户端
let Store = new Redis().client
// 注册接口
router.post('/signup', async (ctx) => {
  // 获取用户注册的信息
  const { username, studentNum, password, email, code } = ctx.request.body
  // console.log(username, studentNum, password, email, code)
  let findStudent = await StudentModel.findOne({ studentNumber: studentNum })
  // console.log('查找数据库', findStudent)
  if (findStudent.length !== 0) {
    if (findStudent.name === username) {
      // nodeMailer发送验证码的时候会先在redis中存验证码，就是存到reids中
      if (code) {
        // nodemail:${username}`意思是用于存储验证码的key值都是用nodemail+username的组合，用于区分不同的用户
        // code是键值
        const saveCode = await Store.hget(`nodemail:${username}`, 'code')
        const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
        // console.log(1, saveCode)
        // console.log(2, saveExpire)
        if (code === saveCode) {
          if (new Date().getTime() - saveExpire > 0) {
            ctx.body = {
              code: -1,
              msg: '验证码已过期，请重新尝试'
            }
          } else {
            // 前面都没问题就验证用户名是否被注册了
            let user = await UserModel.find({ username })
            if (user.length) {
              ctx.body = {
                code: -1,
                msg: '已被注册'
              }
              return
            }
            // 注册的时候都正确了，写库
            let nuser = await UserModel.create({ username, studentNum, password, email })
            if (nuser) {
              // 进行登录动作，自动登录
              let res = await axios.post('/users/signin', { username: studentNum, password })
              if (res.data && res.data.data.code === 0) {
                ctx.body = {
                  code: 0,
                  msg: '注册成功',
                  user: res.data.user
                }
              } else {
                ctx.body = {
                  code: -1,
                  msg: 'error'
                }
              }
            } else {
              // 写库失败
              ctx.body = {
                code: -1,
                msg: '注册失败'
              }
            }
          }
        } else {
          ctx.body = {
            code: -1,
            msg: '请填写正确的验证码'
          }
        }
      } else {
        // 拦截，要求填写验证码
        ctx.body = {
          code: -1,
          msg: '请填写验证码'
        }
      }
    } else {
      ctx.body = {
        findStudent,
        msg: "学号与姓名不配对，请输入正确的姓名",
        code: 100
      }
    }
  } else {
    ctx.body = {
      findStudent,
      msg: "该学生不在名单中，请和老师确认是否有该学生",
      code: 100
    }
  }
})
// 登录接口
router.post('/signin', async (ctx, next) => {
  // local指的是调用passport-local的local策略，固定写法
  // function (err, user, info, status)是local策略返回的信息
  return Passport.authenticate('local', function (err, user, info, status) {
    if (err) {
      ctx.body = {
        code: -1,
        msg: err
      }
    } else {
      if (user) {
        // console.log(user)
        let payload = { username: user.username, password: user.password }
        // 秘钥
        let secret = 'I_AM_LI'
        const token = jwt.sign(payload, secret, { expiresIn: 60 * 60 * 24 })
        // 做一个登录的动作
        Store.hmset(`usertoken:${user.studentNum}`, 'token', token)
        ctx.body = {
          data: {
            code: 0,
            msg: '登录成功',
            user,
            token
          }
        }
        return ctx.login(user)
      } else {
        // 存在异常
        // console.log('错误')
        ctx.body = {
          data: {
            code: -1,
            msg: info
          }
        }
      }
    }
  })(ctx, next)
})
// 验证码获取接口
router.post('/verify', async (ctx, next) => {
  let username = ctx.request.body.username
  // 从redis获取验证码时间
  const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
  // console.log('当前时间戳1', new Date().getTime())
  // console.log('获取验证码时间戳1', saveExpire)
  if (saveExpire && new Date().getTime() - saveExpire < 0) {
    ctx.body = {
      meta: {
        code: -1,
        msg: '验证请求过于频繁，1分钟内1次'
      }
    }
    return false
  }
  // 发邮件的对象
  let transporter = nodeMailer.createTransport({
    // host:Email.smtp.host,
    // port: 587,
    // 如果是true就监听6465端口，false就是监听其他端口，587
    // secure: false,
    service: 'qq',
    auth: {
      user: Email.smtp.user,
      pass: Email.smtp.pass
    }
  })
  // 接受信息
  let ko = {
    // 调用dbs/config文件中封装好的code方法
    code: Email.smtp.code(),
    // 设置过期时间
    expire: Email.smtp.expire(),
    // 发验证码给谁
    email: ctx.request.body.email,
    // 我使用哪个用户名发验证码给谁
    user: ctx.request.body.username
  }
  // 邮件中的内容
  let mailOptions = {
    // Email.smtp.user调用config中的user方法，告诉用户是谁发的邮件
    from: `"认证邮件" <${Email.smtp.user}>`,
    // 发验证码给谁
    to: ko.email,
    // 主题
    subject: '玉师校园管理系统注册码',
    // 告诉用户验证码，显示内容
    html: `您好${ko.user}，欢迎注册玉师校园宿舍管理系统，您的验证码是${ko.code}`
  }
  // 开始发送邮件
  await transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      // 这里应该是报警信息
      return console.log(error)
    } else {
      // 存值到redis里面
      Store.hmset(`nodemail:${ko.user}`, 'code', ko.code, 'expire', ko.expire, 'email', ko.email)
    }
  })
  ctx.body = {
    meta: {
      code: 0,
      msg: '验证码已发送，可能会有延时，有效期1分钟'
    }
  }
})
// 退出接口
router.get('/exit', async (ctx, next) => {
  // 做一个注销的动作，删除该用户session
  await ctx.logout()
  // 检查现在是不是登录状态，也就是验证是不是成功注销了
  if (!ctx.isAuthenticated()) {
    ctx.body = {
      code: 0
    }
  } else {
    ctx.body = {
      code: -1
    }
  }
})
// 获取用户名接口
router.get('/getUser', async (ctx) => {
  // 检查现在是不是登录状态，isAuthenticated是passport中定义好的方法，检测用户是否存在session中
  if (ctx.isAuthenticated()) {
    const { username, email } = ctx.session.passport.user
    ctx.body = {
      user: username,
      email
    }
  } else {
    ctx.body = {
      user: '',
      email: ''
    }
  }
})
// 权限用户查询
router.get('/permissin', async (ctx) => {
  let where = {
    role: ctx.query.role
  }
  let result = await UserModel.find(where)
  // 数组过滤，将密码移除
  result.map(valid => {
    valid.password = '******'
    valid.role = valid.role === 'admin' ? '超级管理员' : valid.role === 'general' ? '宿舍管理员' : valid.role === 'inspector' ? '学生卫生纪检员' : '学生'
  })
  if (result) {
    ctx.body = {
      result,
      meta: {
        msg: '请求成功',
        code: 200
      }
    }
  } else {
    ctx.body = {
      result,
      meta: {
        msg: '没有数据',
        code: 100
      }
    }
  }

})
// 权限修改
router.post('/permissinChange', async (ctx) => {
  let {
    studentNum,
    role
  } = ctx.request.body
  console.log(studentNum, role)
  let query = { studentNum }
  let newRole = { role }
  await UserModel.updateOne(query, newRole, (err, res) => {
    // console.log(res)
    if (err) {
      ctx.body = {
        msg: '修改失败',
        code: -1
      }
    } else if (res.n === 0) {
      // res是一个对象：如果存在就会返回 {n:1,nmodified: 1,ok:1}
      ctx.body = {
        msg: '修改失败,没有找到该用户',
        code: -1
      }
    } else {
      ctx.body = {
        msg: '修改成功',
        code: 0
      }
    }
  })
})
// 用户搜索角色为学生的用户
router.get('/findUser', async (ctx) => {
  let { query } = ctx.query
  let nameReg = new RegExp("[\\u4E00-\\u9FFF]+")
  let studentNum = new RegExp("[0-9]")
  let where = {}
  if (nameReg.test(query)) {
    where = {
      username: query
    }
    let result1 = await UserModel.find(where, null)
    // 将用户名字重复，且角色是学生的用户过滤出来
    let result = result1.filter(valid => {
      return valid.role === 'student'
    })
    if (result.length) {
      ctx.body = {
        result,
        meta: {
          msg: "请求数据成功",
          code: 200
        }
      }
    } else {
      ctx.body = {
        result,
        meta: {
          msg: `角色为学生的用户中没有名字为：${query}，请确认是否存在该用户或该用户为其他角色`,
          code: 100
        }
      }
    }

  } else if (studentNum.test(query)) {
    where = {
      studentNum: query
    }
    let result1 = await UserModel.find(where, null)
    // 将用户名字重复，且角色是学生的用户过滤出来
    let result = result1.filter(valid => {
      return valid.role === 'student'
    })
    if (result.length) {
      ctx.body = {
        result,
        meta: {
          msg: "请求数据成功",
          code: 200
        }
      }
    } else {
      ctx.body = {
        result,
        meta: {
          msg: `角色为学生的用户中没有学号为：${query}，请确认是否存在该用户或该用户为其他角色`,
          code: 100
        }
      }
    }

  }
})
// 添加学生卫生检查员允许上传卫生表的宿舍楼宇
router.get('/iptAllowTower', async ctx => {
  let where = {
    inspector: ctx.query.inspector,
    studentNum: ctx.query.studentNum,
    class: ctx.query.class,
    towers: ctx.query.towers
  }
  // 先判断之前是不是宿检员
  let isIPT = await inspectorsModel.find({ studentNum: where.studentNum })
  if (isIPT.length !== 0) {
    // 老宿检员，修改权限
    let query = {
      studentNum: where.studentNum
    }
    let newTowers = {
      towers: where.towers
    }
    await inspectorsModel.updateOne(query, newTowers, (err, res) => {
      if (err) {
        ctx.body = {
          meta: {
            msg: '修改失败',
            code: -1
          }
        }
      } else if (res.n === 0) {
        // res是一个对象：如果存在就会返回 {n:1,nmodified: 1,ok:1}
        ctx.body = {
          meta: {
            msg: '修改失败,没有找到该学生',
            code: -1
          }
        }
      } else {
        ctx.body = {
          meta: {
            msg: '修改成功',
            code: 0
          }
        }
      }
    })
  } else {
    // 新的宿检员，分配权限
    let code
    const addInspector = new inspectorsModel(where)
    try {
      await addInspector.save()
      code = 0
    } catch (e) {
      code = -1
    }
    ctx.body = {
      meta: {
        msg: code === 0 ? '分配成功' : '分配失败，请联系管理员',
        code: code
      }
    }
  }
})
// 修改学生卫生上传的楼宇
router.get('/iptChangeTower', async ctx => {
  let query = {
    studentNum: ctx.query.studentNum
  }
  let newTowers = {
    towers: ctx.query.towers
  }
  await inspectorsModel.updateOne(query, newTowers, (err, res) => {
    if (err) {
      ctx.body = {
        meta: {
          msg: '修改失败',
          code: -1
        }
      }
    } else if (res.n === 0) {
      // res是一个对象：如果存在就会返回 {n:1,nmodified: 1,ok:1}
      ctx.body = {
        meta: {
          msg: '修改失败,没有找到该学生',
          code: -1
        }
      }
    } else {
      ctx.body = {
        meta: {
          msg: '修改成功',
          code: 0
        }
      }
    }
  })
})
// 删除学生上传权限
router.get('/iptDelete', async (ctx, next) => {
  const deleteIPT = { studentNum: ctx.query.studentNum }
  console.log('66666:', ctx.query)
  let code
  try {
    await inspectorsModel.remove(deleteIPT, null)
    code = 0
  } catch (e) {
    code = -1
  }
  ctx.body = {
    meta: {
      msg: '删除成功',
      code: code
    }
  }
})
// 查看学生拥有权限的楼宇
router.get('/iptFindTower', async (ctx, next) => {
  const user = { studentNum: ctx.query.studentNum }
  let result = await inspectorsModel.find(user, null)
  if (result.length !== 0) {
    ctx.body = {
      result,
      meta: {
        msg: "请求数据成功",
        code: 200
      }
    }
  } else {
    ctx.body = {
      result,
      meta: {
        msg: "该学生还没有分配权限，请为该学生分配权限",
        code: 100
      }
    }
  }
})

export default router
